<?php header("content-Type: text/html; charset=utf-8");session_start();
$dbconfig=empty($_SESSION['dbconfig'])?array('db_host'=>'','db_user'=>'','db_pw'=>'','db_name'=>'',):$_SESSION['dbconfig'];
if(!empty($_POST['db_user']) && !empty($_POST['db_name'])){$dbconfig=$_POST;$_SESSION['dbconfig']=$dbconfig;}
$db_host = $dbconfig['db_host'];		//数据库服务器
$db_user = $dbconfig['db_user'];			//数据库用户名
$db_pw = $dbconfig['db_pw'];				//数据库密码
$db_name = $dbconfig['db_name'];	//数据库名
$db_pconnect = 0;			//是否启用持久连接
if(empty($db_user)){echo tpl_header().tpl_sitting();exit;}@extract($_GET);
if(!empty($act) && $act=='logout'){$_SESSION['dbconfig']='';message("注销成功!",'?act=');exit;}//注销
$db = new db;$db->connect($db_host, $db_user, $db_pw, $db_name, $db_pconnect);
if(empty($act))$act='';echo tpl_menu();
if($act=='import'){//导入
    if(!empty($dosubmit)){
        $fileid = isset($fileid) ? $fileid : 1;$filepath = $pre.$fileid.'.sql';
        if(file_exists('./data/'.$filepath)){
        	$sql = cache_read($filepath,'');sql_execute($sql);$fileid++;
        	message("数据文件 $filepath 导入成功!","?pre=".$pre."&fileid=".$fileid."&dosubmit=1&act=import");
        }else{message("数据库恢复成功!");}
    }else{echo tpl_import();exit;}
}else {//导出
    if(!empty($dosubmit)){
        if(!is_writable('./data/')) message('数据无法备份到服务器!请检查 ./data 目录是否可写。');if(empty($pre))$pre='NULL';
        $query = $db->query("SHOW TABLES FROM ".$db_name);$k = 0;while($r = $db->fetch_row($query)){if($pre=='NULL' || str_exists($r[0],$pre)){$tables[$k] = $r[0];$k++;}}
    	$fileid = isset($fileid) ? $fileid : 1;if($fileid==1 && $tables) 
    	{if(!isset($tables) || !is_array($tables)) message('请选择要备份的数据表!');$random = mt_rand(1000, 9999);cache_write('bakup_tables.php', $tables);}
    	else{if(!$tables = cache_read('bakup_tables.php')) message('请选择要备份的数据表!');}
    	$sqldump = '';$tableid = isset($tableid) ? $tableid - 1 : 0;
    	$startfrom = isset($startfrom) ? intval($startfrom) : 0;$tablenumber = count($tables);for($i = $tableid; $i < $tablenumber && strlen($sqldump) < $sizelimit * 1000; $i++)
    	{$sqldump .= sql_dumptable($tables[$i], $startfrom, strlen($sqldump));$startfrom = 0;}
    	if(trim($sqldump)){$sqldump = "#xiaogg QQ756663992 Created\n# ----\n\n\n".$sqldump;$tableid = $i;
    		$filename = $db_name.'_'.date('Ymd').'_'.$random.'_'.$fileid.'.sql';$fileid++;$bakfile = './data/'.$filename;
    		file_put_contents($bakfile, $sqldump);
    		message("备份文件 $filename 写入成功!", '?sizelimit='.$sizelimit.'&tableid='.$tableid.'&fileid='.$fileid.'&startfrom='.$startrow.'&random='.$random.'&dosubmit=1');
    	}else{cache_delete('bakup_tables.php');message('备份完毕!');}exit;
    }else{echo tpl_explort();exit;}
}
function tpl_header(){return '<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui"><title>MYSQL精简备份恢复</title>
<style>body{font-family:"宋体";font-size:16px;line-height:20px;padding:0px;color:#333;}a{display: inline-block;padding: 0 12px 1px; line-height: 32px; color: #FFF;text-shadow: 0 -1px 0 rgba(0,0,0,0.25);font-size: 14px;background-color: #abbac3;border: 5px solid #abbac3;cursor: pointer; vertical-align: middle;position: relative;}
form{margin-left:10px;}input,select{width:auto;height: 34px;padding:0px 3px;margin:3px;line-height: 1.42857143;color: #555;background-color: #fff;border: 1px solid #ccc;
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075);box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;}
input[type="submit"]{color: #fff;background-color: #428bca;border-color: #357ebd;padding:5px 10px;}</style></head><body>';}
function tpl_footer(){return '</body></html>';};
function tpl_menu(){$str= tpl_header().'<a href="?act=">导出</a> <a href="?act=import">导入</a> <a href="?act=logout">注销</a><br><br>';return $str;}
function tpl_import(){
    $str= '<form action="" method="get">';
    $str.= '前缀:'.tpl_pres().'<br>开始卷:<input name="fileid" type="text" value="1"/>';
    $str.= '<br><input name="dosubmit" type="hidden" value="1"/><input name="act" type="hidden" value="import"/>';
    $str.= '<input type="submit" value="从data目录恢复" /></form><br>';return $str.tpl_footer();
}
function tpl_explort(){
    $str= '<form action="" method="get">';
    $str.= '数据库前缀:<input name="pre" type="text" value=""/><br>分卷大小:<input name="sizelimit" type="text" value="2048"/>K<br>';
    $str.= '<input name="dosubmit" type="hidden" value="1"/><input type="submit" value="备份到data目录" /></form>';return $str.tpl_footer();
}
function tpl_sitting(){
    $str= "<form action='' method='post'>服务器主机：<input name='db_host' value='localhost' type='text'/><br/>";
	$str.= "数据库用户：<input name='db_user' value='' type='text'/><br/>";
	$str.= "数据库密码：<input name='db_pw' value='' type='password'/><br/>";
	$str.= "数据库表名：<input name='db_name' value='' type='text'/><br/><input type='submit' value='设置'/></form>";return $str.tpl_footer();
}
function tpl_pres(){
    $pres=array();$str='<select name="pre">';
    foreach (glob("./data/*_1.sql") as $filename) {
        $name=basename($filename);$pre=str_replace('1.sql','',$name);
        $str.='<option value="'.$pre.'">'.$pre.'</option>';
    }$str.='</select>';return $str;
}
function cache_read($file, $mode = 'i'){$cachefile = './data/'.$file;if(!file_exists($cachefile)) return array();return $mode == 'i' ? include $cachefile : file_get_contents($cachefile);}
function cache_write($file, $string, $type = 'array'){
	if(is_array($string)){$type = strtolower($type);
	if($type == 'array'){$string = "<?php\n return ".var_export($string,TRUE).";\n?>";}
	elseif($type == 'constant'){$data='';foreach($string as $key => $value) $data .= "define('".strtoupper($key)."','".addslashes($value)."');\n";$string = "<?php\n".$data."\n?>";}}
	file_put_contents('./data/'.$file, $string);
}
function sql_execute($sql){global $db;$sqls = sql_split($sql);if(is_array($sqls)){foreach($sqls as $sql){if(trim($sql) != '') {$db->query($sql);}}}else{$db->query($sqls);}	return true;}
function sql_split($sql) {    
	global $db_charset, $db;
	if($db->version() > '4.1' && $db_charset) {$sql = preg_replace("/TYPE=(InnoDB|MyISAM|MEMORY)( DEFAULT CHARSET=[^; ]+)?/", "ENGINE=\\1 DEFAULT CHARSET=".$db_charset,$sql);}
	$sql = str_replace("\r", "\n", $sql);$ret = array();$num = 0;
	$queriesarray = explode(";\n", trim($sql));unset($sql);
	foreach($queriesarray as $query) {
		$ret[$num] = '';$queries = explode("\n", trim($query));$queries = array_filter($queries);
		foreach($queries as $query) {$str1 = substr($query, 0, 1);if($str1 != '#' && $str1 != '-') $ret[$num] .= $query;}$num++;
	}return($ret);
}
function str_exists($haystack, $needle){return !(strpos($haystack, $needle) === FALSE);}
function cache_delete($file){return @unlink('./data/'.$file);}
function sql_dumptable($table, $startfrom = 0, $currsize = 0){
	global $db, $sizelimit, $startrow;if(!isset($tabledump)) $tabledump = '';	$offset = 100;
	if(!$startfrom){
		$tabledump = "DROP TABLE IF EXISTS `".$table."`;\n";
		$createtable = $db->query("SHOW CREATE TABLE `".$table."`");
		$create = $db->fetch_row($createtable);
		$tabledump .= $create[1].";\n\n";
	}
	$tabledumped = 0;$numrows = $offset;
	while($currsize + strlen($tabledump) < $sizelimit * 1000 && $numrows == $offset){
		$tabledumped = 1;$rows = $db->query("SELECT * FROM `".$table."` LIMIT $startfrom, $offset");
		$numfields = $db->num_fields($rows);
		$numrows = $db->num_rows($rows);
		while ($row = $db->fetch_row($rows)){
			$comma = "";$tabledump .= "INSERT INTO `".$table."` VALUES(";
			for($i = 0; $i < $numfields; $i++){
				$tabledump .= $comma."'".mysql_real_escape_string($row[$i])."'";$comma = ",";
			}$tabledump .= ");\n";
		}$startfrom += $offset;
	}$startrow = $startfrom;$tabledump .= "\n";return $tabledump;
}
function message($msg,$url_forward='',$ms=1250){echo $msg;if($url_forward){echo '<script type="text/javascript">function redirect(url){window.location=url;}setTimeout("redirect(\''.$url_forward.'\');",'.$ms.');</script>';}exit;}
class db{//Mysql 数据库类
	public $connid;public $querynum = 0;
	public function connect($dbhost, $dbuser, $dbpw, $dbname, $pconnect = 0,$db_charset='utf8'){
		$func = $pconnect == 1 ? 'mysql_pconnect' : 'mysql_connect';
		if(!$this->connid = @$func($dbhost, $dbuser, $dbpw)){echo $this->error();}
		if($this->version() > '4.1' && $db_charset){mysql_query("SET NAMES '".$db_charset."'" , $this->connid);}
		if($this->version() > '5.0'){mysql_query("SET sql_mode=''" , $this->connid);}
		if($dbname){if(!@mysql_select_db($dbname , $this->connid)){$this->halt('Cannot use database '.$dbname);}}
		return $this->connid;
	}
	public function select_db($dbname){return mysql_select_db($dbname , $this->connid);}
	public function query($sql , $type = ''){
		$func = $type == 'UNBUFFERED' ? 'mysql_unbuffered_query' : 'mysql_query';
		if(!($query = $func($sql , $this->connid)) && $type != 'SILENT'){$this->halt('MySQL Query Error', $sql);}$this->querynum++;return $query;
	}
	public function get_one($sql, $type = '', $expires = 3600, $dbname = ''){$query = $this->query($sql, $type, $expires, $dbname);$rs = $this->fetch_array($query);$this->free_result($query);return $rs ;}
	public function fetch_array($query, $result_type = MYSQL_ASSOC){return mysql_fetch_array($query, $result_type);}
	public function affected_rows(){return mysql_affected_rows($this->connid);}
	public function num_rows($query){return mysql_num_rows($query);}
	public function num_fields($query){return mysql_num_fields($query);}
	public function result($query, $row){return @mysql_result($query, $row);}
	public function free_result($query) {return mysql_free_result($query);}
	public function insert_id() {return mysql_insert_id($this->connid);}
	public function fetch_row($query){return mysql_fetch_row($query);}
	public function version() {return mysql_get_server_info($this->connid);}
	public function close(){return mysql_close($this->connid);}
	public function error(){return @mysql_error($this->connid);}
	public function errno(){return intval(@mysql_errno($this->connid)) ;}
	public function halt($message = '', $sql = '')	{exit("MySQL Query:$sql <br> MySQL Error:".$this->error()." <br> MySQL Errno:".$this->errno()." <br> Message:$message");}
}?>